package com.salton123.bmob.helper;


import android.content.Context;
import android.text.TextUtils;

import com.salton123.app.BaseApplication;
import com.salton123.bmob.AppUtils;
import com.salton123.bmob.bean.User;
import com.salton123.bmob.biz.vitrual.AndroidId;
import com.salton123.bmob.biz.vitrual.FeedbackEntity;
import com.salton123.log.XLog;
import com.salton123.util.PreferencesUtils;
import com.salton123.util.RxUtils;

import java.io.File;
import java.util.List;

import cn.bmob.sdkdemo.BuildConfig;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobBatch;
import cn.bmob.v3.BmobObject;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.datatype.BatchResult;
import cn.bmob.v3.datatype.BmobFile;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.QueryListListener;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UploadBatchListener;
import cn.bmob.v3.listener.UploadFileListener;
import cn.bmob.v3.update.AppVersion;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;

/**
 * User: newSalton@outlook.com
 * Date: 2019/6/3 10:52
 * ModifyTime: 10:52
 * Description:
 */
public class BmobHelper {
    public static void init(Context context) {
        Bmob.initialize(context, BuildConfig.BMOB_KEY);
    }

    public static Observable<BmobFile> uploadFile(final String fileLocalPath, final UploadFileListener listener) {
        return Observable.create(new ObservableOnSubscribe<BmobFile>() {
            @Override
            public void subscribe(final ObservableEmitter<BmobFile> emitter) {
                File localFile = new File(fileLocalPath);
                final BmobFile bmobFile = new BmobFile(localFile);
                bmobFile.upload(new UploadFileListener() {
                    @Override
                    public void onProgress(Integer value) {
                        if (listener != null) {
                            listener.onProgress(value);
                        }
                    }

                    @Override
                    public void onStart() {
                        if (listener != null) {
                            listener.onStart();
                        }
                    }

                    @Override
                    public void done(BmobException e) {
                        if (listener != null) {
                            listener.done(e);
                        }
                        if (e != null) {
                            emitter.onNext(bmobFile);
                        }
                    }

                    @Override
                    public void doneError(int code, String msg) {
                        if (listener != null) {
                            listener.doneError(code, msg);
                        }
                    }
                });
            }
        });
    }

    public static Observable<User> register(final String username, final String password) {
        return Observable.create(new ObservableOnSubscribe<User>() {
            @Override
            public void subscribe(final ObservableEmitter<User> emitter) throws Exception {
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                user.signUp(new SaveListener<User>() {
                    @Override
                    public void done(User user, BmobException e) {
                        if (e == null) {
                            emitter.onNext(user);
                        } else {
                            emitter.onError(e);
                        }
                    }
                });
            }
        });
    }

    public static Observable<User> login(final String username, final String password) {
        return Observable.create(new ObservableOnSubscribe<User>() {
            @Override
            public void subscribe(final ObservableEmitter emitter) throws Exception {
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                user.login(new SaveListener<User>() {
                    @Override
                    public void done(User user, BmobException e) {
                        if (e == null) {
                            emitter.onNext(user);
                            PreferencesUtils.putString(BaseApplication.getInstance(), "username", username);
                            PreferencesUtils.putString(BaseApplication.getInstance(), "password", password);
                        } else {
                            emitter.onError(e);
                        }
                    }
                });
            }
        });
    }


    public static Observable<List<BmobFile>> uploadBatch(
            final List<String> localFileList,
            final UploadBatchListener listener) {
        return Observable.create(new ObservableOnSubscribe<List<BmobFile>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<BmobFile>> emitter) throws Exception {
                BmobFile.uploadBatch(localFileList.toArray(new String[]{}),
                        new UploadBatchListener() {
                            @Override
                            public void onSuccess(List<BmobFile> list, List<String> list1) {
                                if (listener != null) {
                                    listener.onSuccess(list, list1);
                                }
                                for (BmobFile item : list) {
                                    if (item.getLocalFile().exists()) {
                                        item.getLocalFile().delete();
                                    }
                                }
                                if (list1.size() == localFileList.size()) {
                                    emitter.onNext(list);
                                }
                            }

                            @Override
                            public void onProgress(int i, int i1, int i2, int i3) {
                                if (listener != null) {
                                    listener.onProgress(i, i1, i2, i3);
                                }
                                XLog.i(BmobHelper.class, "i:" + i + ",i1:" + i1 + ",i2:" + i2 + ",i3:" + i3);
                            }

                            @Override
                            public void onError(int i, String s) {
                                if (listener != null) {
                                    listener.onError(i, s);
                                }
                                XLog.i(BmobHelper.class, "i:" + i + ",s:" + s);
                            }
                        });
            }
        });
    }

    public static Observable<Boolean> insertBatch(final List<BmobObject> files) {
        return Observable.create(new ObservableOnSubscribe<Boolean>() {
            @Override
            public void subscribe(final ObservableEmitter<Boolean> emitter) {
                new BmobBatch().insertBatch(files).doBatch(new QueryListListener<BatchResult>() {
                    @Override
                    public void done(List<BatchResult> list, BmobException e) {
                        if (e != null) {
                            XLog.i(BmobHelper.class, "e:" + e);
                        }
                        for (BatchResult item : list) {
                            emitter.onNext(item.isSuccess());
                        }
                    }
                });
            }
        });
    }

    public static String getLoginUserId() {
        if (BmobUser.isLogin()) {
            return BmobUser.getCurrentUser(BmobUser.class).getObjectId();
        } else {
            return "";
        }
    }

    public static <T extends BmobObject> void getCloudApkList(int pageSize, int page, FindListener<T> listener) {
        BmobQuery<T> query = new BmobQuery<>();
        query.setLimit(pageSize);
        query.setSkip(page * pageSize);
        // query.addWhereEqualTo("channel", com.salton123.corelite.BuildConfig.CHANNEL);
        query.findObjects(listener);
    }

    public static Observable<AppVersion> chengVersionUpdate() {
        return Observable.create(new ObservableOnSubscribe<AppVersion>() {
            @Override
            public void subscribe(final ObservableEmitter<AppVersion> emitter) throws Exception {
                BmobQuery<AppVersion> query = new BmobQuery<>();
                query.setLimit(1);
                query.setSkip(0);
                query.addWhereGreaterThan("version_i", AppUtils.getVersionCode(BaseApplication.getInstance()));
                query.findObjects(new FindListener<AppVersion>() {
                    @Override
                    public void done(List<AppVersion> list, BmobException e) {
                        if (e == null && list != null && list.size() > 0) {
                            AppVersion appVersion = list.get(0);
                            emitter.onNext(appVersion);
                            emitter.onComplete();
                        }
                    }
                });
            }
        }).compose(RxUtils.<AppVersion>schedulersTransformer());
    }

    public static void feedback(String content) {
        if (!TextUtils.isEmpty(content)) {
            FeedbackEntity entity = new FeedbackEntity();
            entity.ownerId = getLoginUserId();
            entity.content = content;
            entity.save(new SaveListener<String>() {
                @Override
                public void done(String s, BmobException e) {

                }
            });
        }
    }

    public static void active(final String id) {
        BmobQuery<AndroidId> query = new BmobQuery();
        query.addWhereEqualTo("androidId", id);
        query.findObjects(new FindListener<AndroidId>() {
            @Override
            public void done(List<AndroidId> list, BmobException e) {
                if (list == null || list.size() == 0) {
                    AndroidId androidId = new AndroidId(id);
                    androidId.save(new SaveListener<String>() {
                        @Override
                        public void done(String s, BmobException e) {
                            XLog.i(this, "active success:" + e);
                        }
                    });
                }
            }
        });
    }

}
